﻿using System;

namespace LAPI.Business.Gestores
{
    /// <summary>
    /// Clase que implementa funciones para gestionar operaciones sobre la entidad de base de datos 'Pista'
    /// </summary>
    public class GestorPistas
    {
        /// <summary>
        /// Logger de la clase
        /// </summary>
        private LAPI.Core.Logging.ILogger logger;

        /// <summary>
        /// Constructor
        /// </summary>
        public GestorPistas()
        {
            logger = LAPI.Core.Logging.LoggerFactory.CreateLogger(type: typeof(GestorPistas));
        }

        #region Getter
        /// <summary>
        /// Método para obtener un listado de todos las pistas (activos y no activos) de un centro deportivo
        /// </summary>
        /// <param name="IdCentroDeportivo">Int con el identificador único del Centro Deportivo</param>
        /// <returns>Una colección del modelo con todas las pistas</returns>
        /// <seealso cref="Pista"/>
        /// <seealso cref="GestorBBDD"/>
        public System.Collections.Generic.List<LAPI.Data.Model.Pista> ObtenerTodos(Int32 IdCentroDeportivo)
        {
            System.Text.StringBuilder sql = new System.Text.StringBuilder();
            LAPI.Data.GestorBBDD oBBDD = LAPI.Data.GestorBBDDFactory.getGestorBBDD();
            System.Collections.Generic.List<LAPI.Data.Model.Pista> result;

            sql.Append("Select ");
            sql.Append(LAPI.Data.Model.Pista.Columns);
            sql.Append(" from ");
            sql.Append(LAPI.Data.Model.Pista.Tables);
            sql.Append(" where pista.id_centrodeportivo = centrodeportivo.id_centrodeportivo");
            sql.Append(" and PISTA.id_centrodeportivo = " + IdCentroDeportivo);

            try
            {
                oBBDD.Abrir();
                result = LAPI.Data.Model.Pista.toModel(oBBDD.Select(sql.ToString()));
                oBBDD.CerrarParcial();
                return result;
            }
            catch (Exception ex)
            {
                oBBDD.Cerrar();
                logger.Error(message: ex.Message, exception: ex);
                return null;
            }           
        }

        /// <summary>
        /// Método para obtener los datos de una Pista, sabiendo su identificador único
        /// </summary>
        /// <param name="IdPista">Int con el identificador único de la Pista</param>
        /// <param name="IdCentroDeportivo">Int con el identificador único del Centro Deportivo al que pertenece</param>
        /// <returns>modelo Pista con los datos</returns>
        /// <seealso cref="Pista"/>
        /// <seealso cref="GestorBBDD"/>
        public LAPI.Data.Model.Pista ObtenerPorID(Int32 IdPista, Int32 IdCentroDeportivo)
        {
            System.Text.StringBuilder sql = new System.Text.StringBuilder();
            LAPI.Data.GestorBBDD oBBDD = LAPI.Data.GestorBBDDFactory.getGestorBBDD();
            System.Collections.Generic.List<LAPI.Data.Model.Pista> result;

            sql.Append("Select ");
            sql.Append(LAPI.Data.Model.Pista.Columns);
            sql.Append(" from ");
            sql.Append(LAPI.Data.Model.Pista.Tables);
            sql.Append(" where id_pista = " + IdPista);

            try
            {
                oBBDD.Abrir();
                result = LAPI.Data.Model.Pista.toModel(oBBDD.Select(sql.ToString()));
                oBBDD.CerrarParcial(); 
                return result[0];
            }
            catch (Exception ex)
            {
                oBBDD.Cerrar();
                logger.Error(message: ex.Message, exception: ex);
                return null;
            }
        }

        /// <summary>
        /// Método para obtener un listado de todas las pistas que pertenecen a un centro deportivo, y que permiten la 
        /// práctica de un deporte
        /// </summary>
        /// <param name="IdCentroDeportivo">Int con el identificador único del Centro Deportivo</param>
        /// <param name="IdDeporte">Int con el identificador único del Deporte</param>
        /// <returns>Una colección del modelo con todas las pistas</returns>
        /// <seealso cref="Pista"/>
        /// <seealso cref="GestorBBDD"/>
        public System.Collections.Generic.List<LAPI.Data.Model.Pista> ObtenerPorCentroYDeporte(Int32 IdCentroDeportivo, Int32 IdDeporte)
        {
            System.Text.StringBuilder sql = new System.Text.StringBuilder();
            LAPI.Data.GestorBBDD oBBDD = LAPI.Data.GestorBBDDFactory.getGestorBBDD();
            System.Collections.Generic.List<LAPI.Data.Model.Pista> result;

            sql.Append("Select ");
            sql.Append(LAPI.Data.Model.Pista.Columns);
            sql.Append(" from ");
            sql.Append(LAPI.Data.Model.Pista.Tables + ", DEPORTESPISTA" );
            sql.Append(" where pista.id_centrodeportivo = centrodeportivo.id_centrodeportivo");
            sql.Append(" and PISTA.id_centrodeportivo = " + IdCentroDeportivo);
            sql.Append(" and DEPORTESPISTA.id_deportes = " + IdDeporte);
            sql.Append(" and DEPORTESPISTA.id_pista = pista.id_pista");
            sql.Append(" and DEPORTESPISTA.activo = 1");
            sql.Append(" and PISTA.activo = 1");
            sql.Append(" and centrodeportivo.activo = 1");

            try
            {
                oBBDD.Abrir();
                result = LAPI.Data.Model.Pista.toModel(oBBDD.Select(sql.ToString()));
                oBBDD.CerrarParcial();
                return result;
            }
            catch (Exception ex)
            {
                oBBDD.Cerrar();
                logger.Error(message: ex.Message, exception: ex);
                return null;
            }
        }

        /// <summary>
        /// Método para filtrar una busqueda de Pista por alguno de estos campos:
        /// <ul>
        /// <li>Descripcion</li>
        /// <li>idpista</li>
        /// </ul>
        /// </summary>
        /// <param name="filtroBusqueda">Diccionario con el filtro de la búsqueda</param>
        /// <param name="IdCentroDeportivo">Int con el identificador único del Centro Deportivo</param>
        /// <returns>Una colección del modelo con todos las pistas</returns>
        /// <seealso cref="Pista"/>
        /// <seealso cref="GestorBBDD"/>
        public System.Collections.Generic.List<LAPI.Data.Model.Pista> ObtenerBusqueda(System.Collections.Hashtable filtroBusqueda, Int32 idCentroDeportivo)
        {
            System.Text.StringBuilder sql = new System.Text.StringBuilder();
            LAPI.Data.GestorBBDD oBBDD = LAPI.Data.GestorBBDDFactory.getGestorBBDD();
            System.Collections.Generic.List<LAPI.Data.Model.Pista> result;

            sql.Append("Select ");
            sql.Append(LAPI.Data.Model.Pista.Columns);
            sql.Append(" from ");
            sql.Append(LAPI.Data.Model.Pista.Tables);
            sql.Append(" where pista.id_centrodeportivo = centrodeportivo.id_centrodeportivo");
            sql.Append(" and PISTA.id_centrodeportivo = " + idCentroDeportivo);

            //Añadimos filtros
            if (filtroBusqueda.ContainsKey("descripcion"))
                sql.Append(" and pista.descripcion like '%" + filtroBusqueda["descripcion"].ToString().Replace('*','%') + "%'");
            if (filtroBusqueda.ContainsKey("idpista"))
                sql.Append(" and id_pista like '%" + filtroBusqueda["idpista"].ToString().Replace('*', '%') + "%'");

            try
            {
                oBBDD.Abrir();
                result = LAPI.Data.Model.Pista.toModel(oBBDD.Select(sql.ToString()));
                oBBDD.CerrarParcial();
                return result;
            }
            catch (Exception ex)
            {
                oBBDD.Cerrar();
                logger.Error(message: ex.Message, exception: ex);
                return null;
            }
        }
    #endregion

        #region Comprobaciones
       

#endregion

        #region insert

        /// <summary>
        /// Método para insertar una nueva pista en la base de datos
        /// </summary>
        /// <param name="datosPista">Modelo con los datos de la Pista a insertar (previamente validados)</param>
        /// <seealso cref="Pista"/>
        /// <seealso cref="GestorBBDD"/>
        public void Insertar(LAPI.Data.Model.Pista datosPista)
        {
            System.Text.StringBuilder sql = new System.Text.StringBuilder();
            LAPI.Data.GestorBBDD oBBDD = LAPI.Data.GestorBBDDFactory.getGestorBBDD();
            Int32 result;

            sql.Append("Insert into ");
            sql.Append(LAPI.Data.Model.Pista.Table);
            sql.Append(" ( ");
            sql.Append(datosPista.ToInsertColumns());
            sql.Append(" ) values ( ");
            sql.Append(datosPista.ToInsertValues());
            sql.Append(" ) ");            

            try
            {
                oBBDD.Abrir();
                result = oBBDD.Insert(sql.ToString());               
                oBBDD.CerrarParcial();
                if (result != 1)
                    throw new Exception("No se ha insertado el registro: " + datosPista);
            }
            catch (Exception ex)
            {
                oBBDD.Cerrar();
                logger.Error(message: ex.Message, exception: ex);
                throw new Exception("No se ha insertado el registro: " + datosPista);
            }           
        }

        #endregion

        #region update

        /// <summary>
        /// Método para actualizar los datos 'cambiantes' de la Pista
        /// </summary>
        /// <param name="datosPista">Modelo con los datos de la Pista</param>
        /// <seealso cref="Pista"/>
        /// <seealso cref="GestorBBDD"/>
        public void Actualizar(LAPI.Data.Model.Pista datosPista)
        {
            System.Text.StringBuilder sql = new System.Text.StringBuilder();
            LAPI.Data.GestorBBDD oBBDD = LAPI.Data.GestorBBDDFactory.getGestorBBDD();
            Int32 result;

            sql.Append("Update ");
            sql.Append(LAPI.Data.Model.Pista.Table);
            sql.Append(" set ");
            sql.Append(datosPista.ToUpdate());
            sql.Append(" where id_pista =" + datosPista.idPista);

            try
            {
                oBBDD.Abrir();
                result = oBBDD.Update(sql.ToString());
                oBBDD.CerrarParcial();
                if (result != 1)
                    throw new Exception("No se ha actualizado el registro: " + datosPista);
            }
            catch (Exception ex)
            {
                oBBDD.Cerrar();
                logger.Error(message: ex.Message, exception: ex);
                throw new Exception("No se ha actualizado el registro: " + datosPista);
            }
        }

        /// <summary>
        /// Método para actualizar el estado de la Pista
        /// </summary>
        /// <param name="datosPista">Modelo con los datos de la Pista</param>
        /// <seealso cref="Pista"/>
        /// <seealso cref="GestorBBDD"/>
        public void ActualizarEstado(LAPI.Data.Model.Pista datosPista)
        {
            System.Text.StringBuilder sql = new System.Text.StringBuilder();
            LAPI.Data.GestorBBDD oBBDD = LAPI.Data.GestorBBDDFactory.getGestorBBDD();
            Int32 result;

            sql.Append("Update ");
            sql.Append(LAPI.Data.Model.Pista.Table);
            sql.Append(" set ");
            sql.Append(datosPista.ToUpdateEstado());
            sql.Append(" where id_pista =" + datosPista.idPista);

            try
            {
                oBBDD.Abrir();
                result = oBBDD.Update(sql.ToString());
                oBBDD.CerrarParcial();
                if (result != 1)
                    throw new Exception("No se ha actualizado el registro: " + datosPista);
            }
            catch (Exception ex)
            {
                oBBDD.Cerrar();
                logger.Error(message: ex.Message, exception: ex);
                throw new Exception("No se ha actualizado el registro: " + datosPista);
            }
        }

        #endregion

        #region delete

        /// <summary>
        /// Método para eliminar una Pista
        /// </summary>
        /// <param name="datosPista">Modelo con los datos de la Pista</param>
        /// <seealso cref="Pista"/>
        /// <seealso cref="GestorBBDD"/>
        public void Eliminar(LAPI.Data.Model.Pista datosPista)
        {
            System.Text.StringBuilder sql = new System.Text.StringBuilder();
            LAPI.Data.GestorBBDD oBBDD = LAPI.Data.GestorBBDDFactory.getGestorBBDD();
            Int32 result;

            sql.Append("Delete from ");
            sql.Append(LAPI.Data.Model.Pista.Table);
            sql.Append(" where id_pista =" + datosPista.idPista);

            try
            {
                oBBDD.Abrir();
                result = oBBDD.Delete(sql.ToString());
                oBBDD.CerrarParcial();
                if (result != 1)
                    throw new Exception("No se ha eliminado el registro: " + datosPista);
            }
            catch (Exception ex)
            {
                oBBDD.Cerrar();
                logger.Error(message: ex.Message, exception: ex);
                throw new Exception("No se ha eliminado el registro: " + datosPista);
            }
        }

        #endregion
    }
}
